/**
 * Copyright (c) 2010-2011 Pierre Labatut
 *
 * This file is part of Space-Chronicles project.
 *
 * Space-Chronicles is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/space-chronicles/>.
 */

package space.game.splash;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import javax.swing.SwingUtilities;

/**
 *
 * @author Pierre
 */
public class CfgSplash {

    final List<InitializationTask> steps = new ArrayList<InitializationTask>();

    /**
     * Add a runnable to the list of task o be processed
     * @param r
     */
    public void submit(final InitializationTask r) {
        if (r == null) {
            throw new IllegalArgumentException();
        }
        steps.add(r);
    }

    public CfgSplash() {
    }

    /**
     * Run all submited task a display a progress bar, plus the task title returned by 
     * toString(). Runnable are runned in the calling thread.
     * @throws RuntimeException when a task failed. The progressbar is hidden before exception raise.
     */
    public void runAll() {
        /**
         * Create a window creation task
         */
        final FutureTask<CfgSplashDialog> startupTask = new FutureTask<CfgSplashDialog>(
                new Callable<CfgSplashDialog>() {

                    public CfgSplashDialog call() throws Exception {
                        final CfgSplashDialog cfgSplashDialog = new CfgSplashDialog();
                        cfgSplashDialog.setVisible(true);
                        return cfgSplashDialog;
                    }
                });
        SwingUtilities.invokeLater(startupTask);

        /**
         * Build de window
         */
        try {
            final CfgSplashDialog dialog = startupTask.get();
            try {
                /**
                 * Run every step
                 */
                for (final InitializationTask task : steps) {
                    final String title = task.title();
                    final int indexOf = steps.indexOf(task);
                    final int size = steps.size();
                    SwingUtilities.invokeLater(new Runnable() {

                        public void run() {
                            dialog.setProgress(title, indexOf, size);
                        }
                    });
                    task.run();

                }
            } finally {
                /**
                 * Hide the progress bar anyway
                 */
                SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        dialog.setVisible(false);
                    }
                });
            }
        } catch (InterruptedException ex) {
            throw new RuntimeException(ex);
        } catch (ExecutionException ex) {
            throw new RuntimeException(ex);
        }
    }
}
